package com.nanbei.thread;

import java.lang.ref.*;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * @ClassDescription: 强、软、弱、虚 四大引用
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/10/11 11:22
 */
public class ReferenceDemo {
    @Override
    protected void finalize() throws Throwable {
        // 当垃圾回收确定没有更多对对象的引用时，由对象上的垃圾回收器调用
        System.out.println("调用 finalize 方法进行垃圾回收 ");
    }
    public static void main(String[] args) {
        // 强引用
        // strongReference();

        // 软引用
        // softReference();

        // 弱引用
        // weakReference();

        // 虚引用
        PhantomReference();

    }

    private static void PhantomReference() {
        MyObject myObject = new MyObject();
        ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue<>();
        PhantomReference<MyObject> phantomReference = new PhantomReference<>(myObject,referenceQueue);
        System.out.println(phantomReference.get());

        ArrayList<byte[]> list = new ArrayList<>();
        new Thread(()->{
            while (true){
                // 将JVM的内存大小设置为 -Xms10m -Xmx15m， 然后不停的往数组中创建值
                list.add(new byte[1024 * 1024]);
                try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
                System.out.println(phantomReference.get() +"\t" + "list add OK");
            }
        },"thread1").start();

        new Thread(()->{
            while (true){
                Reference<? extends MyObject> reference = referenceQueue.poll();
                if (reference!=null){
                    System.out.println("---有虚对象加入队列");
                    break;
                }
            }
        },"thread2").start();
    }

    /**
     * 弱引用
     * 只要一触发GC 就会进行被回收
     */
    private static void weakReference() {
        WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo());
        System.out.println("gc before "+weakReference.get());
        System.gc();
        System.out.println("gc after "+weakReference.get());
    }

    /**
     * 软引用
     * 系统内存不足时回收
     */
    private static void softReference() {
        SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo());
        System.out.println("gc before "+softReference.get());
        try {
            // 将JVM的内存大小设置为10M -Xms10m -Xmx15m， 创建一个20M的数组 导致内存溢出触发GC
            byte[] bytes = new byte[20 * 1024 * 1024];
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("gc after "+softReference.get());
        }
    }

    /**
     * 强引用
     */
    private static void strongReference() {
        MyObject myObject = new MyObject();
        System.out.println("gc before "+myObject);
        myObject = null;
        System.gc();
        System.out.println("gc after "+myObject);
    }
}

class MyObject{
    @Override
    protected void finalize() throws Throwable {
        // 当垃圾回收确定没有更多对对象的引用时，由对象上的垃圾回收器调用
        System.out.println("调用 finalize 方法进行垃圾回收 ");
    }
}
